# (C) Datadog, Inc. 2023-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
import re

_COUNTS = {
    "erlang_mnesia_committed_transactions": "erlang.mnesia.committed_transactions",
    "erlang_mnesia_failed_transactions": "erlang.mnesia.failed_transactions",
    "erlang_mnesia_logged_transactions": "erlang.mnesia.logged_transactions",
    "erlang_mnesia_restarted_transactions": "erlang.mnesia.restarted_transactions",
    "erlang_vm_msacc_alloc_seconds_total": "erlang.vm.msacc.alloc_seconds",
    "erlang_vm_msacc_aux_seconds_total": "erlang.vm.msacc.aux_seconds",
    "erlang_vm_msacc_bif_seconds_total": "erlang.vm.msacc.bif_seconds",
    "erlang_vm_msacc_busy_wait_seconds_total": "erlang.vm.msacc.busy_wait_seconds",
    "erlang_vm_msacc_check_io_seconds_total": "erlang.vm.msacc.check_io_seconds",
    "erlang_vm_msacc_emulator_seconds_total": "erlang.vm.msacc.emulator_seconds",
    "erlang_vm_msacc_ets_seconds_total": "erlang.vm.msacc.ets_seconds",
    "erlang_vm_msacc_gc_full_seconds_total": "erlang.vm.msacc.gc_full_seconds",
    "erlang_vm_msacc_gc_seconds_total": "erlang.vm.msacc.gc_seconds",
    "erlang_vm_msacc_nif_seconds_total": "erlang.vm.msacc.nif_seconds",
    "erlang_vm_msacc_other_seconds_total": "erlang.vm.msacc.other_seconds",
    "erlang_vm_msacc_port_seconds_total": "erlang.vm.msacc.port_seconds",
    "erlang_vm_msacc_send_seconds_total": "erlang.vm.msacc.send_seconds",
    "erlang_vm_msacc_sleep_seconds_total": "erlang.vm.msacc.sleep_seconds",
    "erlang_vm_msacc_timers_seconds_total": "erlang.vm.msacc.timers_seconds",
    "erlang_vm_statistics_bytes_output_total": "erlang.vm.statistics.bytes_output",
    "erlang_vm_statistics_bytes_received_total": "erlang.vm.statistics.bytes_received",
    "erlang_vm_statistics_context_switches": "erlang.vm.statistics.context_switches",
    "erlang_vm_statistics_garbage_collection_bytes_reclaimed": "erlang.vm.statistics.garbage_collection.bytes_reclaimed",  # noqa: E501
    "erlang_vm_statistics_garbage_collection_number_of_gcs": "erlang.vm.statistics.garbage_collection.number_of_gcs",
    "erlang_vm_statistics_garbage_collection_words_reclaimed": "erlang.vm.statistics.garbage_collection.words_reclaimed",  # noqa: E501
    "erlang_vm_statistics_reductions_total": "erlang.vm.statistics.reductions",
    "erlang_vm_statistics_runtime_milliseconds": "erlang.vm.statistics.runtime_milliseconds",
    "erlang_vm_statistics_wallclock_time_milliseconds": "erlang.vm.statistics.wallclock_time_milliseconds",
    "rabbitmq_auth_attempts_failed_total": "auth_attempts.failed",
    "rabbitmq_auth_attempts_succeeded_total": "auth_attempts.succeeded",
    "rabbitmq_auth_attempts_total": "auth_attempts",
    # The detailed endpoint exposes the same authorization metrics but split by tag and with slightly different names.
    "rabbitmq_auth_attempts_detailed_failed_total": "auth_attempts.failed",
    "rabbitmq_auth_attempts_detailed_succeeded_total": "auth_attempts.succeeded",
    "rabbitmq_auth_attempts_detailed_total": "auth_attempts",
    "rabbitmq_channel_get_ack_total": "channel.get.ack",
    "rabbitmq_channel_get_empty_total": "channel.get.empty",
    "rabbitmq_channel_get_total": "channel.get",
    "rabbitmq_channel_messages_acked_total": "channel.messages.acked",
    "rabbitmq_channel_messages_confirmed_total": "channel.messages.confirmed",
    "rabbitmq_channel_messages_delivered_ack_total": "channel.messages.delivered.ack",
    "rabbitmq_channel_messages_delivered_total": "channel.messages.delivered",
    "rabbitmq_channel_messages_published_total": "channel.messages.published",
    "rabbitmq_channel_messages_redelivered_total": "channel.messages.redelivered",
    "rabbitmq_channel_messages_unroutable_dropped_total": "channel.messages.unroutable.dropped",
    "rabbitmq_channel_messages_unroutable_returned_total": "channel.messages.unroutable.returned",
    "rabbitmq_channel_process_reductions_total": "channel.process_reductions",
    "rabbitmq_channels_closed_total": "channels.closed",
    "rabbitmq_channels_opened_total": "channels.opened",
    "rabbitmq_connection_incoming_bytes_total": "connection.incoming_bytes",
    "rabbitmq_connection_incoming_packets_total": "connection.incoming_packets",
    "rabbitmq_connection_outgoing_bytes_total": "connection.outgoing_bytes",
    "rabbitmq_connection_outgoing_packets_total": "connection.outgoing_packets",
    "rabbitmq_connection_process_reductions_total": "connection.process_reductions",
    "rabbitmq_connections_closed_total": "connections.closed",
    "rabbitmq_connections_opened_total": "connections.opened",
    "rabbitmq_erlang_gc_reclaimed_bytes_total": "erlang.gc.reclaimed_bytes",
    "rabbitmq_erlang_gc_runs_total": "erlang.gc.runs",
    "rabbitmq_erlang_scheduler_context_switches_total": "erlang.scheduler.context_switches",
    "rabbitmq_global_messages_acknowledged_total": "global.messages.acknowledged",
    "rabbitmq_global_messages_confirmed_total": "global.messages.confirmed",
    "rabbitmq_global_messages_dead_lettered_confirmed_total": "global.messages.dead_lettered.confirmed",
    "rabbitmq_global_messages_dead_lettered_delivery_limit_total": "global.messages.dead_lettered.delivery_limit",
    "rabbitmq_global_messages_dead_lettered_expired_total": "global.messages.dead_lettered.expired",
    "rabbitmq_global_messages_dead_lettered_maxlen_total": "global.messages.dead_lettered.maxlen",
    "rabbitmq_global_messages_dead_lettered_rejected_total": "global.messages.dead_lettered.rejected",
    "rabbitmq_global_messages_delivered_consume_auto_ack_total": "global.messages.delivered.consume_auto_ack",
    "rabbitmq_global_messages_delivered_consume_manual_ack_total": "global.messages.delivered.consume_manual_ack",
    "rabbitmq_global_messages_delivered_get_auto_ack_total": "global.messages.delivered.get_auto_ack",
    "rabbitmq_global_messages_delivered_get_manual_ack_total": "global.messages.delivered.get_manual_ack",
    "rabbitmq_global_messages_delivered_total": "global.messages.delivered",
    "rabbitmq_global_messages_get_empty_total": "global.messages.get_empty",
    "rabbitmq_global_messages_received_confirm_total": "global.messages.received_confirm",
    "rabbitmq_global_messages_received_total": "global.messages.received",
    "rabbitmq_global_messages_redelivered_total": "global.messages.redelivered",
    "rabbitmq_global_messages_routed_total": "global.messages.routed",
    "rabbitmq_global_messages_unroutable_dropped_total": "global.messages.unroutable.dropped",
    "rabbitmq_global_messages_unroutable_returned_total": "global.messages.unroutable.returned",
    "rabbitmq_io_read_bytes_total": "io.read_bytes",
    "rabbitmq_io_read_ops_total": "io.read_ops",
    "rabbitmq_io_read_time_seconds_total": "io.read_time_seconds",
    "rabbitmq_io_reopen_ops_total": "io.reopen_ops",
    "rabbitmq_io_seek_ops_total": "io.seek_ops",
    "rabbitmq_io_seek_time_seconds_total": "io.seek_time_seconds",
    "rabbitmq_io_sync_ops_total": "io.sync_ops",
    "rabbitmq_io_sync_time_seconds_total": "io.sync_time_seconds",
    "rabbitmq_io_write_bytes_total": "io.write_bytes",
    "rabbitmq_io_write_ops_total": "io.write_ops",
    "rabbitmq_io_write_time_seconds_total": "io.write_time_seconds",
    "rabbitmq_msg_store_read_total": "msg_store.read",
    "rabbitmq_msg_store_write_total": "msg_store.write",
    "rabbitmq_queue_disk_reads_total": "queue.disk_reads",
    "rabbitmq_queue_disk_writes_total": "queue.disk_writes",
    "rabbitmq_queue_index_read_ops_total": "queue.index.read_ops",
    "rabbitmq_queue_index_write_ops_total": "queue.index.write_ops",
    "rabbitmq_queue_messages_published_total": "queue.messages.published",
    "rabbitmq_queue_process_reductions_total": "queue.process_reductions",
    "rabbitmq_queues_created_total": "queues.created",
    "rabbitmq_queues_declared_total": "queues.declared",
    "rabbitmq_queues_deleted_total": "queues.deleted",
    "rabbitmq_raft_term_total": "raft.term",
    "rabbitmq_schema_db_disk_tx_total": "schema.db.disk_tx",
    "rabbitmq_schema_db_ram_tx_total": "schema.db.ram_tx",
}

_GAUGES = {
    "erlang_mnesia_held_locks": "erlang.mnesia.held_locks",
    "erlang_mnesia_lock_queue": "erlang.mnesia.lock_queue",
    "erlang_mnesia_memory_usage_bytes": "erlang.mnesia.memory_usage_bytes",
    "erlang_mnesia_tablewise_memory_usage_bytes": "erlang.mnesia.tablewise_memory_usage_bytes",
    "erlang_mnesia_tablewise_size": "erlang.mnesia.tablewise_size",
    "erlang_mnesia_transaction_coordinators": "erlang.mnesia.transaction_coordinators",
    "erlang_mnesia_transaction_participants": "erlang.mnesia.transaction_participants",
    "erlang_vm_allocators": "erlang.vm.allocators",
    "erlang_vm_atom_count": "erlang.vm.atom_count",
    "erlang_vm_atom_limit": "erlang.vm.atom_limit",
    "erlang_vm_dirty_cpu_schedulers": "erlang.vm.dirty_cpu_schedulers",
    "erlang_vm_dirty_cpu_schedulers_online": "erlang.vm.dirty_cpu_schedulers_online",
    "erlang_vm_dirty_io_schedulers": "erlang.vm.dirty_io_schedulers",
    "erlang_vm_dist_node_queue_size_bytes": "erlang.vm.dist.node_queue_size_bytes",
    "erlang_vm_dist_node_state": "erlang.vm.dist.node_state",
    "erlang_vm_dist_port_input_bytes": "erlang.vm.dist.port_input_bytes",
    "erlang_vm_dist_port_memory_bytes": "erlang.vm.dist.port_memory_bytes",
    "erlang_vm_dist_port_output_bytes": "erlang.vm.dist.port_output_bytes",
    "erlang_vm_dist_port_queue_size_bytes": "erlang.vm.dist.port_queue.size_bytes",
    "erlang_vm_dist_proc_heap_size_words": "erlang.vm.dist.proc.heap_size_words",
    "erlang_vm_dist_proc_memory_bytes": "erlang.vm.dist.proc.memory_bytes",
    "erlang_vm_dist_proc_message_queue_len": "erlang.vm.dist.proc.message_queue_len",
    "erlang_vm_dist_proc_min_bin_vheap_size_words": "erlang.vm.dist.proc.min_bin_vheap_size_words",
    "erlang_vm_dist_proc_min_heap_size_words": "erlang.vm.dist.proc.min_heap_size_words",
    "erlang_vm_dist_proc_reductions": "erlang.vm.dist.proc.reductions",
    "erlang_vm_dist_proc_stack_size_words": "erlang.vm.dist.proc.stack_size_words",
    # We decided to submit erlang.vm.dist.proc.status as a gauge instead of a service check.
    # We think this is more useful to set up alerting/monitoring for clients.
    "erlang_vm_dist_proc_status": "erlang.vm.dist.proc.status",
    "erlang_vm_dist_proc_total_heap_size_words": "erlang.vm.dist.proc.total_heap_size_words",
    "erlang_vm_dist_recv_avg_bytes": "erlang.vm.dist.recv.avg_bytes",
    "erlang_vm_dist_recv_bytes": "erlang.vm.dist.recv_bytes",
    "erlang_vm_dist_recv_cnt": "erlang.vm.dist.recv.cnt",
    "erlang_vm_dist_recv_dvi_bytes": "erlang.vm.dist.recv.dvi_bytes",
    "erlang_vm_dist_recv_max_bytes": "erlang.vm.dist.recv.max_bytes",
    "erlang_vm_dist_send_avg_bytes": "erlang.vm.dist.send.avg_bytes",
    "erlang_vm_dist_send_bytes": "erlang.vm.dist.send_bytes",
    "erlang_vm_dist_send_cnt": "erlang.vm.dist.send.cnt",
    "erlang_vm_dist_send_max_bytes": "erlang.vm.dist.send.max_bytes",
    "erlang_vm_dist_send_pend_bytes": "erlang.vm.dist.send.pend_bytes",
    "erlang_vm_ets_limit": "erlang.vm.ets_limit",
    "erlang_vm_logical_processors": "erlang.vm.logical_processors",
    "erlang_vm_logical_processors_available": "erlang.vm.logical_processors.available",
    "erlang_vm_logical_processors_online": "erlang.vm.logical_processors.online",
    "erlang_vm_memory_atom_bytes_total": "erlang.vm.memory.atom_bytes_total",
    "erlang_vm_memory_bytes_total": "erlang.vm.memory.bytes_total",
    "erlang_vm_memory_dets_tables": "erlang.vm.memory.dets_tables",
    "erlang_vm_memory_ets_tables": "erlang.vm.memory.ets_tables",
    "erlang_vm_memory_processes_bytes_total": "erlang.vm.memory.processes_bytes_total",
    "erlang_vm_memory_system_bytes_total": "erlang.vm.memory.system_bytes_total",
    "erlang_vm_port_count": "erlang.vm.port_count",
    "erlang_vm_port_limit": "erlang.vm.port_limit",
    "erlang_vm_process_count": "erlang.vm.process_count",
    "erlang_vm_process_limit": "erlang.vm.process_limit",
    "erlang_vm_schedulers": "erlang.vm.schedulers",
    "erlang_vm_schedulers_online": "erlang.vm.schedulers_online",
    "erlang_vm_smp_support": {'name': "erlang.vm.smp_support", 'type': 'gauge'},
    "erlang_vm_statistics_dirty_cpu_run_queue_length": "erlang.vm.statistics.dirty_cpu_run_queue_length",
    "erlang_vm_statistics_dirty_io_run_queue_length": "erlang.vm.statistics.dirty_io_run_queue_length",
    "erlang_vm_statistics_run_queues_length": "erlang.vm.statistics.run_queues_length",
    "erlang_vm_thread_pool_size": "erlang.vm.thread_pool_size",
    "erlang_vm_threads": {'name': "erlang.vm.threads", 'type': 'gauge'},
    "erlang_vm_time_correction": {'name': "erlang.vm.time_correction", 'type': 'gauge'},
    "erlang_vm_wordsize_bytes": "erlang.vm.wordsize_bytes",
    "process_start_time_seconds": "process_start_time_seconds",
    "rabbitmq_alarms_file_descriptor_limit": {'name': "alarms.file_descriptor_limit", 'type': 'gauge'},
    "rabbitmq_alarms_free_disk_space_watermark": {'name': "alarms.free_disk_space.watermark", 'type': 'gauge'},
    "rabbitmq_alarms_memory_used_watermark": {'name': "alarms.memory_used_watermark", 'type': 'gauge'},
    "rabbitmq_channel_acks_uncommitted": "channel.acks_uncommitted",
    "rabbitmq_channel_consumers": "channel.consumers",
    "rabbitmq_channel_messages_unacked": "channel.messages.unacked",
    "rabbitmq_channel_messages_uncommitted": "channel.messages.uncommitted",
    "rabbitmq_channel_messages_unconfirmed": "channel.messages.unconfirmed",
    "rabbitmq_channel_prefetch": "channel.prefetch",
    "rabbitmq_channels": "channels",
    "rabbitmq_cluster_vhost_status": "cluster.vhost_status",
    "rabbitmq_cluster_exchange_name": "cluster.exchange_name",
    "rabbitmq_cluster_exchange_bindings": "cluster.exchange_bindings",
    "rabbitmq_connection_channels": "connection.channels",
    "rabbitmq_connection_pending_packets": "connection.pending_packets",
    "rabbitmq_connections": "connections",
    "rabbitmq_consumer_prefetch": "consumer_prefetch",
    "rabbitmq_consumers": "consumers",
    "rabbitmq_disk_space_available_bytes": "disk_space.available_bytes",
    "rabbitmq_disk_space_available_limit_bytes": "disk_space.available_limit_bytes",
    "rabbitmq_erlang_net_ticktime_seconds": "erlang.net.ticktime_seconds",
    "rabbitmq_erlang_processes_limit": "erlang.processes_limit",
    "rabbitmq_erlang_processes_used": "erlang.processes_used",
    "rabbitmq_erlang_scheduler_run_queue": "erlang.scheduler.run_queue",
    "rabbitmq_erlang_uptime_seconds": "erlang.uptime_seconds",
    "rabbitmq_global_consumers": "global.consumers",
    "rabbitmq_global_publishers": "global.publishers",
    "rabbitmq_process_max_fds": "process.max_fds",
    "rabbitmq_process_max_tcp_sockets": "process.max_tcp_sockets",
    "rabbitmq_process_open_fds": "process.open_fds",
    "rabbitmq_process_open_tcp_sockets": "process.open_tcp_sockets",
    "rabbitmq_process_resident_memory_bytes": "process.resident_memory_bytes",
    "rabbitmq_queue_consumer_capacity": "queue.consumer_capacity",
    "rabbitmq_queue_consumer_utilisation": "queue.consumer_utilisation",
    "rabbitmq_queue_consumers": "queue.consumers",
    "rabbitmq_queue_head_message_timestamp": "queue.head_message_timestamp",
    "rabbitmq_queue_messages": "queue.messages",
    "rabbitmq_queue_messages_bytes": "queue.messages.bytes",
    "rabbitmq_queue_messages_paged_out": "queue.messages.paged_out",
    "rabbitmq_queue_messages_paged_out_bytes": "queue.messages.paged_out_bytes",
    "rabbitmq_queue_messages_persistent": "queue.messages.persistent",
    "rabbitmq_queue_messages_persistent_bytes": "queue.messages.persistent_bytes",
    "rabbitmq_queue_messages_ram": "queue.messages.ram",
    "rabbitmq_queue_messages_ram_bytes": "queue.messages.ram_bytes",
    "rabbitmq_queue_messages_ready": "queue.messages.ready",
    "rabbitmq_queue_messages_ready_bytes": "queue.messages.ready_bytes",
    "rabbitmq_queue_messages_ready_ram": "queue.messages.ready_ram",
    "rabbitmq_queue_messages_unacked": "queue.messages.unacked",
    "rabbitmq_queue_messages_unacked_bytes": "queue.messages.unacked_bytes",
    "rabbitmq_queue_messages_unacked_ram": "queue.messages.unacked_ram",
    "rabbitmq_queue_process_memory_bytes": "queue.process_memory_bytes",
    "rabbitmq_queues": "queues",
    "rabbitmq_raft_entry_commit_latency_seconds": "raft.entry_commit_latency_seconds",
    "rabbitmq_raft_log_commit_index": "raft.log.commit_index",
    "rabbitmq_raft_log_last_applied_index": "raft.log.last_applied_index",
    "rabbitmq_raft_log_last_written_index": "raft.log.last_written_index",
    "rabbitmq_raft_log_snapshot_index": "raft.log.snapshot_index",
    "rabbitmq_resident_memory_limit_bytes": "resident_memory_limit_bytes",
}
# We submit these metrics as gauges so that we have access to their tags.
_INFO = {
    "rabbitmq_build_info": {
        'name': 'build_info',
        "type": 'gauge',
    },
    "rabbitmq_identity_info": {
        'name': 'identity_info',
        "type": 'gauge',
    },
}
_SUMMARIES = {
    "telemetry_scrape_duration_seconds": "telemetry.scrape.duration_seconds",
    "telemetry_scrape_encoded_size_bytes": "telemetry.scrape.encoded_size_bytes",
    "telemetry_scrape_size_bytes": "telemetry.scrape.size_bytes",
}

_RENAME_RABBITMQ_TO_DATADOG = {
    **{re.sub("_total$", "", k): v for k, v in _COUNTS.items()},
    **_GAUGES,
    **_SUMMARIES,
    **_INFO,
}

_DETAILED_FAMILIES = {
    # Generic metrics
    "connection_churn_metrics": {
        "rabbitmq_connections_opened_total",
        "rabbitmq_connections_closed_total",
        "rabbitmq_channels_opened_total",
        "rabbitmq_channels_closed_total",
        "rabbitmq_queues_declared_total",
        "rabbitmq_queues_created_total",
        "rabbitmq_queues_deleted_total",
    },
    "node_coarse_metrics": {
        "rabbitmq_process_open_fds",
        "rabbitmq_process_open_tcp_sockets",
        "rabbitmq_process_resident_memory_bytes",
        "rabbitmq_disk_space_available_bytes",
        "rabbitmq_erlang_processes_used",
        "rabbitmq_erlang_gc_runs_total",
        "rabbitmq_erlang_gc_reclaimed_bytes_total",
        "rabbitmq_erlang_scheduler_context_switches_total",
    },
    "node_metrics": {
        "rabbitmq_process_max_fds",
        "rabbitmq_process_max_tcp_sockets",
        "rabbitmq_resident_memory_limit_bytes",
        "rabbitmq_disk_space_available_limit_bytes",
        "rabbitmq_erlang_processes_limit",
        "rabbitmq_erlang_scheduler_run_queue",
        "rabbitmq_erlang_net_ticktime_seconds",
        "rabbitmq_erlang_uptime_seconds",
    },
    "node_persister_metrics": {
        "rabbitmq_io_read_ops_total",
        "rabbitmq_io_read_bytes_total",
        "rabbitmq_io_write_ops_total",
        "rabbitmq_io_write_bytes_total",
        "rabbitmq_io_sync_ops_total",
        "rabbitmq_io_seek_ops_total",
        "rabbitmq_io_reopen_ops_total",
        "rabbitmq_schema_db_ram_tx_total",
        "rabbitmq_schema_db_disk_tx_total",
        "rabbitmq_msg_store_read_total",
        "rabbitmq_msg_store_write_total",
        "rabbitmq_queue_index_read_ops_total",
        "rabbitmq_queue_index_write_ops_total",
        "rabbitmq_io_read_time_seconds_total",
        "rabbitmq_io_write_time_seconds_total",
        "rabbitmq_io_sync_time_seconds_total",
        "rabbitmq_io_seek_time_seconds_total",
    },
    "ra_metrics": {
        "rabbitmq_raft_term_total",
        "rabbitmq_raft_log_snapshot_index",
        "rabbitmq_raft_log_last_applied_index",
        "rabbitmq_raft_log_commit_index",
        "rabbitmq_raft_log_last_written_index",
        "rabbitmq_raft_entry_commit_latency_seconds",
    },
    "auth_attempt_metrics": {
        "rabbitmq_auth_attempts_total",
        "rabbitmq_auth_attempts_succeeded_total",
        "rabbitmq_auth_attempts_failed_total",
    },
    # NOTE: These names are not what's in the docs, instead they exclude the
    # same aggergated metrics as the `auth_attempt_metrics` family.
    "auth_attempt_detailed_metrics": {
        "rabbitmq_auth_attempts_total",
        "rabbitmq_auth_attempts_succeeded_total",
        "rabbitmq_auth_attempts_failed_total",
    },
    # Queue Metrics
    "queue_coarse_metrics": {
        'rabbitmq_queue_messages',
        'rabbitmq_queue_messages_ready',
        'rabbitmq_queue_process_reductions_total',
        'rabbitmq_queue_messages_unacked',
    },
    'queue_consumer_count': {"rabbitmq_queue_consumers"},
    "queue_metrics": {
        "rabbitmq_queue_consumers",
        "rabbitmq_queue_consumer_capacity",
        "rabbitmq_queue_consumer_utilisation",
        "rabbitmq_queue_process_memory_bytes",
        "rabbitmq_queue_messages_ram",
        "rabbitmq_queue_messages_ram_bytes",
        "rabbitmq_queue_messages_ready_ram",
        "rabbitmq_queue_messages_unacked_ram",
        "rabbitmq_queue_messages_persistent",
        "rabbitmq_queue_messages_persistent_bytes",
        "rabbitmq_queue_messages_bytes",
        "rabbitmq_queue_messages_ready_bytes",
        "rabbitmq_queue_messages_unacked_bytes",
        "rabbitmq_queue_messages_paged_out",
        "rabbitmq_queue_messages_paged_out_bytes",
        "rabbitmq_queue_head_message_timestamp",
        "rabbitmq_queue_disk_reads_total",
        "rabbitmq_queue_disk_writes_total",
    },
    # Connection/channel metrics
    "connection_coarse_metrics": {
        "rabbitmq_connection_incoming_bytes_total",
        "rabbitmq_connection_outgoing_bytes_total",
        "rabbitmq_connection_process_reductions_total",
    },
    "connection_metrics": {
        "rabbitmq_connection_incoming_packets_total",
        "rabbitmq_connection_outgoing_packets_total",
        "rabbitmq_connection_pending_packets",
        "rabbitmq_connection_channels",
    },
    "channel_metrics": {
        "rabbitmq_channel_consumers",
        "rabbitmq_channel_messages_unacked",
        "rabbitmq_channel_messages_unconfirmed",
        "rabbitmq_channel_messages_uncommitted",
        "rabbitmq_channel_acks_uncommitted",
        "rabbitmq_consumer_prefetch",
        "rabbitmq_channel_prefetch",
    },
    "channel_process_metrics": {"rabbitmq_channel_process_reductions_total"},
    "channel_exchange_metrics": {
        "rabbitmq_channel_messages_published_total",
        "rabbitmq_channel_messages_confirmed_total",
        "rabbitmq_channel_messages_unroutable_returned_total",
        "rabbitmq_channel_messages_unroutable_dropped_total",
    },
    "channel_queue_metrics": {
        "rabbitmq_channel_get_ack_total",
        "rabbitmq_channel_get_total",
        "rabbitmq_channel_messages_delivered_ack_total",
        "rabbitmq_channel_messages_delivered_total",
        "rabbitmq_channel_messages_redelivered_total",
        "rabbitmq_channel_messages_acked_total",
        "rabbitmq_channel_get_empty_total",
    },
    "channel_queue_exchange_metrics": {"rabbitmq_queue_messages_published_total"},
    # Virtual hosts and exchange metrics.
    "vhost_status": {"rabbitmq_cluster_vhost_status"},
    "exchange_names": {"rabbitmq_cluster_exchange_name"},
    "exchange_bindings": {"rabbitmq_cluster_exchange_bindings"},
}
# Most metrics in /metrics/detailed are also found in /metrics/per-object.
# There are however also a few that don't occur in /metrics/per-object.
_DETAILED_ONLY_METRICS = {
    "rabbitmq_cluster_vhost_status",
    "rabbitmq_cluster_exchange_name",
    "rabbitmq_cluster_exchange_bindings",
}


def unaggregated_renames_and_exclusions(endpoint):
    """Generate metrics renaming mapping and exclusions for an unaggregated endpoint.

    The exclusions are a set of raw metric names which we want to collect only from the unaggregated endpoint
    and exclude from the aggregated endpoint if we enable it.
    """
    exclude_from_agg = set()
    exclude_from_agg = set()
    for metric_fam in re.findall(r"family=([^&\s]+)", endpoint):
        exclude_from_agg |= _DETAILED_FAMILIES.get(metric_fam, set())
    metric_renames = {}
    for k, v in _RENAME_RABBITMQ_TO_DATADOG.items():
        keep_prefix = k in (_INFO.keys() | _DETAILED_ONLY_METRICS)
        k = k if keep_prefix else re.sub("^rabbitmq_", "rabbitmq_detailed_", k)
        metric_renames[k] = v
    return metric_renames, exclude_from_agg


def aggregated_renames(exclude_unaggregated_metrics):
    """Generate metric renaming mapping for the aggregated endpoint.

    This takes into account any metrics that we should not collect because we already get them from
    the unaggregated endpoint.
    """
    return {
        **{re.sub("_total$", "", k): v for k, v in _COUNTS.items() if k not in exclude_unaggregated_metrics},
        **{k: v for k, v in _GAUGES.items() if k not in exclude_unaggregated_metrics},
        **_SUMMARIES,
        **_INFO,
    }
